<?php
namespace control;

/*
*产品需求计划类
*/

class productDemandClass extends adIndexClass
{
    private const page = 'productDemand';
    private const title = '产品需求计划';
    private const table = 'product_demands';

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'recordDate'          => [
                        'name'  => "单据日期",
                        'width' => 100,
                        'sort' => 1,
                    ],
                    'orderNo' => [
                        'name'  => "销售单号",
                        'width' => 200,
                        'sort' => 1,
                    ],
                    'contract'  => [
                        'name'  => "合同编号",
                        'width' => 200,
                    ],
                    'companyName'  => [
                        'name'  => '客户',
                        'width' => 150,
                    ],
                    'stid'  => [
                        'name'  => '销售员',
                        'width' => 100,
                    ],
                    'code'         => [
                        'name'  => '产品编码',
                        'width' => 150,
                        'sort' => 1,
                    ],
                    'materialName'          => [
                        'name'  => '产品名称',
                        'width' => 150,
                    ],
                    'model'          => [
                        'name'  => '规格型号',
                        'width' => 150,
                    ],
                    'unit'          => [
                        'name'  => '单位',
                        'width' => 60,
                    ],
                    'text'          => [
                        'name'  => '备注',
                        'width' => 200,
                    ],
                    'num'          => [
                        'name'  => '订单数量',
                        'width' => 100,
                    ],
                    'stockNum'          => [
                        'name'  => '库存数量',
                        'width' => 100,
                    ],
                    'productNum'          => [
                        'name'  => '已生产数量',
                        'width' => 100,
                    ],
                    'residue'          => [
                        'name'  => '剩余待生产数量',
                        'width' => 120,
                    ]
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "状态" => checkbox(array('name'=>'isClear','value'=>['未清','已清'],'checked'=>['未清'])),
                ],
                [
                    "销售订单号" => text(array("name" => "orderNo")),
                    "合同编号"   => text(array("name" => "contractNo")),
                    "产品编码"   => text(array("name" => "code")),
                ],
                [
                    "产品名称"   => text(array("name" => "materialName")),
                    '销售员'  => selectMultiple(["name" => "stid", 'table' => "staff", 'sqlId' => 'stid', 'sqlField' => 'name', 'class' => 'width200']),
                    "客户" => clientProfileClass::kehuSelect(array('title' => '')),
                ],
                [
                    '单据日期' => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /*列表-查询条件*/
    public function home()
    {
        $html = $this->homeOptions(false);
        //控件
        $button='';
        if ($this->power(self::page,'edit')){
            $button = "<span class='spanButton' onclick=\"commitOrder()\">生成生产计划</span>
                        <span class='spanButton' onclick=\"outsourceChange()\">转到委外</span>
                        <span class='spanButton' onclick=\"purchaseChange()\">转到外购</span>
                        <span class='spanButton' onclick=\"layer('".self::page."','mark','listForm')\">标记为已清</span>".componentClass::tipComponent('生产数量已经满足销售数量可标记为已清');//生产数量是否已经满足了销售单数量要求
        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    /*客户列表-查询结果*/
    public function homeSearch()
    {
        //like查询数组
        $like = array(
            "b.orderNo" => $this->post('orderNo'),//证件编号
            "c.name" => $this->post('materialName'),
            "c.code" => $this->post('code'),
        );
        //全等查询数组
        $equal = array(
            "b.khid" => $this->post('khid'),
            "b.stid" => $this->post('stid'),
            "a.coid"=>self::$coid,
            "b.state"=>'已确认'
        );
        $and ='';
        if ($this->post('createTime')) {
            //单据日期
            $and.=self::timeComparison($this->post('createTime'),field: 'b.recordDate');
        }
        if ($this->post('isClear')) {
            $isClear = [];
            if (in_array('已清',$this->post('isClear'))){
                $isClear[] = 1;
            }
            if (in_array('未清',$this->post('isClear'))){
                $isClear[] = 0;
            }
            //单据日期
            $and.=" and isClear in ('".implode("','",$isClear)."')";
        }
        //获取查询结果
        $where = search(array("like" => $like, "=" => $equal)) . $and;
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'b.recordDate desc,a.list',
            "sort" => $this->post('list_sort') ?: "asc",
            "array"   => array(),
        ));
        $page = $this->page(array(
            "table" => "product_demands as a join sale_order as b on a.sourceId = b.id join material as c on c.id = a.materialId",
            'field'=>"a.*,b.text,b.stid,b.orderNo,b.recordDate,b.contractId,b.khid,c.code,c.name as materialName,c.model",
            "where" => $where,
            "order" => $orderBy['orderBy']
        ));
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        //获取记录
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = array(
                "box" => array("name" => "listId", "value" => $array['id']),
            );
            //已生产数量
            $productNum = find(array(
                'table'=>"machining_in_order as a join machining_in_order_detail as b on a.id = b.orderId join material as mat on b.materialId = mat.id",
                'single'=>"a.state = '已确认' and b.sourceId in (select id from machining_order_mx where sourceId = '$array[id]')",
                'field'=>"ifnull(SUM(CASE WHEN b.unit = mat.unit_one THEN b.num*mat.unit_one_num WHEN b.unit = mat.unit_two THEN b.num*mat.unit_two_num ELSE b.num END),0) AS num"
            ))['num'];
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'contract':
                        $contract = query('sales_contract',"id = '$array[contractId]'");
                        $row[] = $contract['orderNo'];
                        break;
                    case 'companyName':
                        $kehu = query('kehu',"khid = '$array[khid]'");
                        $row[] = $kehu['companyName'];
                        break;
                    case 'stid':
                        $row[] = self::findStaff($array['stid']);
                        break;
                    case 'text':
                        $saleOrderMx = query('sale_order_detail',"id = '$array[sourceMxId]'");
                        $row[] = $saleOrderMx['text'];
                        break;
                    case 'num':
                        $row[] = self::lostZero($array['num'],'numPrecision');
                        break;
                    case 'stockNum':
                        $stockNum = inventoryBalanceClass::inventoryNum($array['materialId'], unit:$array['unit']);//库存数量
                        $row[] = $stockNum;
                        break;
                    case 'productNum':
                        $row[] = machiningOrderClass::material_num_change($array['materialId'],'',$array['unit'],$productNum);
                        break;
                    case 'residue':
                        $row[] = $array['num']-$productNum;
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        $totalQuery = find([
            'table'  => "product_demands as a join sale_order as b on a.sourceId = b.id join material as c on c.id = a.materialId",
            'single' => $where,
            'field'  => "ifnull(sum(a.num),0) as num",
        ]);
        // 已生产数量，已确认的生产入库单数量
        // 单位转换 先将machining_in_order_detail的数量转为主单位数量(CASE WHEN mx.unit = c.unit_one THEN mx.num*c.unit_one_num WHEN mx.unit = c.unit_two THEN mx.num*c.unit_two_num ELSE mx.num END)
        // 再将主单位数量转为semi_demands的单位数量（主单位数量/semi_demands的单位转换数量）
        $machining_in_order_detail = find(array(
            'table'=>"product_demands as a join sale_order as b on a.sourceId = b.id join material as c on c.id = a.materialId join machining_order_mx as mom on a.id = mom.sourceId join machining_in_order_detail as mx on mx.sourceId = mom.id",
            'single'=> $where . " and mx.orderId in (select id from machining_in_order where state = '已确认') ",
            'field'=>"ifnull(SUM((CASE WHEN mx.unit = c.unit_one THEN mx.num*c.unit_one_num WHEN mx.unit = c.unit_two THEN mx.num*c.unit_two_num ELSE mx.num END)/(CASE WHEN a.unit = c.unit_one THEN c.unit_one_num WHEN a.unit = c.unit_two THEN c.unit_two_num ELSE 1 END)),0) AS num"
        ));
        $total    = [
            'num'        => self::lostZero($totalQuery['num'], 'numPrecision'),
            'productNum'   => self::lostZero($machining_in_order_detail['num'], 'numPrecision'),
            'residue' => self::formattingFigure($totalQuery['num'] - $machining_in_order_detail['num'], 'numPrecision'),
        ];
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "total"       => $total,
        ));
        //返回
        $json['html'] = $page['hint'] . "<form name='listForm'>" . $li . "</form>".$this->js() . $page['button'] . clear;
        return json_encode($json, 320);
    }
    public function mark(): bool|string
    {
        //生成表单
        $html = $this->layerEdit(array("table" => array(
            array(
                "提示：" => "是否标记所选数据为已清？",
            ),
        )));
        //返回
        return $this->layer(array("title" => "提示", "height" => 165, "html" => $html, 'formTwo' => 'listForm'));
    }
    public function markEdit(): bool|string
    {
        $listId = $this->post('listId');
        if (static::is_null_array($listId)){
            $json['warn'] = '请选择数据';
        }elseif (!$this->power(self::page,'edit')){
            $json['warn'] = '您还没有'.self::title.'的编辑权限';
        }else{
            $x = 0;
            $text = '';
            foreach ($listId as $id){
                $product_demands = query('product_demands',"id = '$id'");
                $warn = update(array('table'=>'product_demands','field'=>['isClear'=>1],'where'=>"id = '$id'"));
                $material = query('material',"id = '$product_demands[materialId]'");
                if ($warn =='更新成功'){
                    $x++;
                    $text.="产品需求【{$product_demands['id']}】,产品【{$material['code']}-{$material['name']}-{$material['model']}】标记为已清<br>";
                }else{
                    $text.="产品需求【{$product_demands['id']}】,产品【{$material['code']}-{$material['name']}-{$material['model']}】标记已清失败<br>";
                }
            }
            $text=$this->control['name'].'标记了产品需求如下：'.$text;
            $this->logText(["type" => self::page, "text" => $text]);
            $json['warn'] = 2;
            $_SESSION['warn'] = "成功标记了{$x}条数据";
        }
        return json_encode($json,320);
    }
    public function js(): string
    {
        return <<<eof
<script>
//生成生产计划单
function commitOrder(){
     cxDialog('是否确认生成生产计划单?', () => {
                let arr = [];
                $("[name='listForm'] input[name='listId[]']:checked").each(function () {
                    if ($(this).val() && $(this).val() !== 'on') {
                        arr.push($(this).val());
                    }
                });
                if (arr.length ===0){
                    msg('请选择数据','error')
                    return false;
                }
                let listId = arr.join(",");
                newIframe('生产计划', root+'control/adIndex.html?cla=machiningOrder&fun=edit&source=productDemand&listId='+listId,'生产制造','生产计划')
        }, () => {
          // click no callback
        });
}
//转到委外
function outsourceChange(){
    cxDialog('是否确认将所选的物料转到委外需求中?', () => {
           subForm('listForm',root+'control/adIndex.html?cla={$this->get('cla')}&fun=outsourceChange');
        }, () => {
          // click no callback
        });
}
//转到外购
function purchaseChange(){
    cxDialog('是否确认将所选的物料转到外购需求中?', () => {
           subForm('listForm',root+'control/adIndex.html?cla={$this->get('cla')}&fun=purchaseChange');
        }, () => {
          // click no callback
        });
}
</script>
eof;

    }

    /**
     * 转到外购需求中
     */
    public function purchaseChange(){
        $listId = $this->post('listId');
        if (static::is_null_array($listId)) {
            $json['warn'] = '请选择数据';
        }elseif (!$this->power(self::page,'edit')){
            $json['warn'] = '您还没有'.self::title.'的编辑权限';
        } else {
            $x = 0;
            $text = '';
            foreach ($listId as $id) {
                $info = query(self::table,"id = '$id'");
                $sourceInfo = query($info['sourceTable'],"id = '$info[sourceId]'");
                $material = query("material"," id = '$info[materialId]' and supplyControl like '%允许采购%' ","id");
                if (!$info['isClear'] && !empty($material['id'])){
                    $lastSupplier = find(array(
                        'table' => 'purchase_order as a join purchase_order_detail as b on a.id = b.orderId',
                        "single" => "b.materialId = '$info[materialId]' and a.state = '已确认' order by list desc",
                        'field' => "supplierId"
                    ));
                    $warn = static::insert(array(
                        'table' => 'purchase_demands',
                        'field' => [
                            'id'=>suiji(),
                            'coid'=>self::$coid,
                            'sourceType'=>$info['sourceTable']=='sale_order'?'销售订单':'',
                            'sourceId'=>$info['sourceId'],
                            'sourceTable'=>$info['sourceTable'],
                            'sourceMxId'=>$info['sourceMxId'],
                            'sourceNo'=>$sourceInfo['orderNo'],
                            'sourceDate'=>$sourceInfo['recordDate'],
                            'materialId'=>$info['materialId'],
                            'num'=>$info['num'],
                            'unit'=>$info['unit'],
                            'supplierId'=>$lastSupplier['supplierId']??'',
                            'sourceText'=>'产品需求转外购需求',
                            'targetId'=>$info['id'],
                            'targetTable'=>self::table,
                        ],
                    ));

                    if ($warn == '新增成功') {
                        update(array('table'=>self::table,'field'=>['isClear'=>1],'where'=>"id = '$id'"));
                        $x++;
                        $text .= "产品需求中订单【{$sourceInfo['orderNo']}】的物料【".materialClass::getName($info['materialId'])."】，ID：【{$info['id']}】转到了外购需求中<br>";
                    } else {
                        $text .= "产品需求中订单【{$sourceInfo['orderNo']}】的物料【".materialClass::getName($info['materialId'])."】，ID：【{$info['id']}】转到外购需求失败<br>";
                        break;
                    }
                }else{
                    $text .= "产品需求中订单【{$sourceInfo['orderNo']}】的物料【".materialClass::getName($info['materialId'])."】，ID：【{$info['id']}】已清或该物料不允许采购，不可转到外购需求<br>";
                }

            }
            if ($text){
                $text = $this->control['name'] . '批量转外购需求表中如下：' . $text;
            }
            $this->logText(["type" => self::page, "text" => $text]);
            $json['warn'] = 2;
            $_SESSION['warn'] = "成功操作了{$x}条数据";

        }
        return json_encode($json, 320);
    }
    /**
     * 转到委外需求中
     * @return false|string
     */
    public function outsourceChange(){
        $listId = $this->post('listId');
        if (static::is_null_array($listId)) {
            $json['warn'] = '请选择数据';
        }elseif (!$this->power(self::page,'edit')){
            $json['warn'] = '您还没有'.self::title.'的编辑权限';
        } else {
            $x = 0;
            $text = '';
            foreach ($listId as $id) {
                $info = query(self::table,"id = '$id'");
                $sourceInfo = query($info['sourceTable'],"id = '$info[sourceId]'");
                $material = query("material"," id = '$info[materialId]' and supplyControl like '%允许委外%' ","id");
                if (!$info['isClear'] && !empty($material['id'])){
                    $warn = static::insert(array(
                        'table' => 'outsource_demands',
                        'field' => [
                            'id'=>suiji(),
                            'coid'=>self::$coid,
                            'sourceType'=>$info['sourceTable']=='sale_order'?'销售订单':'',
                            'sourceId'=>$info['sourceId'],
                            'sourceTable'=>$info['sourceTable'],
                            'sourceMxId'=>$info['sourceMxId'],
                            'sourceDate'=>$sourceInfo['recordDate'],
                            'sourceNo'=>$sourceInfo['orderNo'],
                            'materialId'=>$info['materialId'],
                            'num'=>$info['num'],
                            'unit'=>$info['unit'],
                            'targetId'=>$info['id'],
                            'targetTable'=>self::table,
                            'sourceText'=>'产品需求转委外需求',
                        ],
                        ));

                    if ($warn == '新增成功') {
                        update(array('table'=>self::table,'field'=>['isClear'=>1],'where'=>"id = '$id'"));
                        $x++;
                        $text .= "产品需求中订单【{$sourceInfo['orderNo']}】的物料【".materialClass::getName($info['materialId'])."】，ID：【{$info['id']}】转到了委外需求中<br>";
                    } else {
                        $text .= "产品需求中订单【{$sourceInfo['orderNo']}】的物料【".materialClass::getName($info['materialId'])."】，ID：【{$info['id']}】转到委外需求失败<br>";
                        break;
                    }
                }else{
                    $text .= "产品需求中订单【{$sourceInfo['orderNo']}】的物料【".materialClass::getName($info['materialId'])."】，ID：【{$info['id']}】已清或该物料不允许委外，不可转到委外需求<br>";
                }

            }
            if ($text){
                $text = $this->control['name'] . '批量转委外需求表中如下：' . $text;
            }
            $this->logText(["type" => self::page, "text" => $text]);
            $json['warn'] = 2;
            $_SESSION['warn'] = "成功操作了{$x}条数据";

        }
        return json_encode($json, 320);
    }

}
